﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using DevComponents.DotNetBar;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using PlanningGIS.ArcGIS;
using PlanningGIS.Framework;
using PlanningGIS.Framework.Rule;
using PlanningGIS.Report;
using PlanningGIS.Util.Convertor;
using PlanningGIS.Win.Controls;
using PlanningGIS.Util.Log;
using PlanningGIS.Engine.Controls;
using PlanningGIS.Framework.Controls;
using ESRI.ArcGIS.Controls;
using PlanningGIS.Util;
using PlanningGIS.MapSheet;
using DevComponents.DotNetBar.SuperGrid;

namespace PlanningGIS.Statistics
{
    public partial class FrmVegetable : Office2007Form 
    {
        private IApplication m_Application = null;
        private IFeatureLayer pFeatureLayer;
        private IElement m_pElement;
        private FrmReport m_pReport;
        private Hashtable m_pCodeAndNameHash = null;

        /// <summary>
        /// 打开范围面
        /// </summary>
        private OpenDataDialog frmAddData = new OpenDataDialog();

        /// <summary>
        /// 地图关联对象
        /// </summary>
        private IHookHelper m_HookHelp = null;

        /// <summary>
        /// 绘制工具构建对象
        /// </summary>
        private ToolCreator _ToolCreator = null;


        /// <summary>
        /// 结合表选择构建对象
        /// </summary>
        private SheetCreator _SheetCreator = null;

        /// <summary>
        /// 测区选择构建对象
        /// </summary>
        private AreaCreator _AreaCreator = null;

        private int idxFcode;
        private int idxName;

        public IFeatureLayer FeatureLayer
        { 
            get { return pFeatureLayer; } 
        }

        public FrmVegetable(IApplication hook)
        {
            InitializeComponent();
            m_Application = hook;
            m_HookHelp = new HookHelper();
            m_HookHelp.Hook = (hook as IFramework).Object;
            //getAreaControl1.Application = m_Application;

            _SheetCreator = new SheetCreator(spgrdSheet, false);
            _SheetCreator.Hook = m_HookHelp.Hook;
            _SheetCreator.IsToMap = true;

            _AreaCreator = new AreaCreator(spgrdArea);
            _AreaCreator.Hook = m_HookHelp.Hook;

            List<ValueName> btns = new List<ValueName>()
            {
                new ValueName(){Value="ToolDrawRectangle",Name="绘制矩形"},
                new ValueName(){Value="ToolDrawPolygon",Name="绘制多边形"},
                new ValueName(){Value="ToolDrawCircle",Name="绘制圆"}
            };
            _ToolCreator = new ToolCreator(btnDrawExtent, m_HookHelp.Hook);
            _ToolCreator.HideForm = true;
            _ToolCreator.Create(btns, true);
            _ToolCreator.DrawFinished += OnDrawFinished;
            regionTree.Hook = m_HookHelp.Hook;

            lyrCbo.ShapeType = zjgisShapeType.Polygon;
            lyrCbo.OnCreate((m_Application as IFramework).Object);
            string featClsName = StatisticConfigHelper.StatisticConfig.植被绿化率统计.要素类名称;
            
            try
            {
                lyrCbo.SetFeatureClassName(featClsName);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
            FillHashtable();

        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
            Close();
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            if (lyrCbo.SelectedLayer == null)
            {
                MsgHelper.ShowWarningMsgbox("请先选择数据！");
                return;
            }

            pFeatureLayer = lyrCbo.SelectedLayer as IFeatureLayer;

            if (pFeatureLayer == null)
            {
                MsgHelper.ShowWarningMsgbox("请选择居民地面数据！");
                return;
            }

            idxFcode = pFeatureLayer.FeatureClass.FindField(AppConfig.SystemConfig.常用字段.分类代码);
            if (idxFcode == -1)
            {
                MsgHelper.ShowWarningMsgbox("所选数据的字段不满足要求,无法进行统计!");
                pFeatureLayer = null;
                return;
            }

            IGeometry pGeometry;
            switch (sptbctlGeo.SelectedTab.Text)
            {
                case "图幅": //按图幅导出
                    pGeometry = (IPolygon)_SheetCreator.GetSelectGeometry();
                    break;
                case "自定义范围": //按自定义范围
                    pGeometry = (IPolygon)_ToolCreator.Geometry;
                    break;

                case "行政区":
                    pGeometry = (IPolygon)regionTree.SelectedGeometry;
                    break;

                case "测区":
                    pGeometry = (IPolygon)_AreaCreator.GetSelectGeometry();
                    break;

                default:
                    return;
            }
            if (pGeometry == null || pGeometry.IsEmpty)
            {
                MsgHelper.ShowWarningMsgbox("请先设置统计范围！");
                return;
            }

            IPolygon pPolygon = pGeometry as IPolygon;
            ITopologicalOperator2 pTopo = pPolygon as ITopologicalOperator2;
            pTopo.IsKnownSimple_2 = false;
            pTopo.Simplify();
            pTopo.IsKnownSimple_2 = true;
            pPolygon.Project(((IGeoDataset)pFeatureLayer.FeatureClass).SpatialReference);

            Application.DoEvents();
            ISpatialFilter pSpatialFilter = new SpatialFilterClass();
            pSpatialFilter.Geometry = pPolygon;
            pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            IFeatureCursor pFeatureCursor = pFeatureLayer.Search(pSpatialFilter, false);
            DataTable pTable = GetDatatableByFeatureclass();
            IFeature pFeature = pFeatureCursor.NextFeature();
            while (pFeature != null)
            {
                AddDatarow(pTable, pFeature, pPolygon);
                pFeature = pFeatureCursor.NextFeature();
            }
            if (pTable.Rows.Count == 0)
            {
                MsgHelper.ShowInfomationMsgbox("尚未检索到植被面数据，请重试！");
                if (m_pElement != null)
                {
                    IGraphicsContainer pGeoContainer = (m_Application.Document as IMxDocument).ActiveView as IGraphicsContainer;
                    pGeoContainer.DeleteElement(m_pElement);
                    m_pElement = null;
                    (m_Application.Document as IMxDocument).ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
                }
                return;
            }

            IArea pArea = pGeometry as IArea;
            double dblArea = Math.Abs(pArea.Area);
            // 
            if (pGeometry.SpatialReference is IGeographicCoordinateSystem)
            {
                ISpatialReference pSpatialReference = GeometryHelper.GetCGCS2000SpatialByX(pArea.Centroid.X);
                IClone pClone = pGeometry as IClone;
                IGeometry pGeomClone = pClone.Clone() as IGeometry;
                pGeomClone.Project(pSpatialReference);
                pArea = pGeomClone as IArea;
                dblArea = pArea.Area;
            }
            // 
            //if (dblArea < 0.000001) return;
            FrmReport pReport = new FrmReport();
            pReport.DataSource = pTable;
            pReport.ParameterValue = dblArea;
            pReport.FullName = AppConfig.ReportPath + @"\Statistic\绿化率统计报表.rpt";
            //pReport.ReportName = "绿化率统计报表.rpt";
            pReport.Text = "绿化率统计报表";
            pReport.ShowDialog();
            (m_Application.Document as IMxDocument).ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
        }

        private static DataTable GetDatatableByFeatureclass()
        {
            DataTable pTable = new DataTable();
            DataColumn pColumn = new DataColumn("OID");
            pColumn.DataType = Type.GetType("System.String");
            pTable.Columns.Add(pColumn);

            pColumn = new DataColumn("FCODE");
            pColumn.DataType = Type.GetType("System.String");
            pTable.Columns.Add(pColumn);

            pColumn = new DataColumn("NAME");
            pColumn.DataType = Type.GetType("System.String");
            pTable.Columns.Add(pColumn);

            pColumn = new DataColumn("AREA");
            pColumn.DataType = Type.GetType("System.Double");
            pTable.Columns.Add(pColumn);

            pColumn = new DataColumn("INTERSECTAREA");
            pColumn.DataType = Type.GetType("System.Double");
            pColumn.DefaultValue = 0.00;
            pTable.Columns.Add(pColumn);

            return pTable;
        }


        private void AddDatarow(DataTable pTable, IFeature pFeature, IGeometry pGeo)
        {
            if (pFeature == null || pTable == null) return;
            DataRow pRow = pTable.NewRow();
            pRow["OID"] = pFeature.OID.ToString();
            string fcode = pFeature.get_Value(idxFcode).ToString();
            string fname = fcode;
            if (m_pCodeAndNameHash.ContainsKey(fcode))
                fname = m_pCodeAndNameHash[fcode].ToString();

            pRow["FCODE"] = fcode;
            pRow["NAME"] = fname;

            IPolygon pPolygon = pFeature.ShapeCopy as IPolygon;

            IArea pArea = pPolygon as IArea;
            double dblArea = Math.Abs(pArea.Area);

            if (pPolygon.SpatialReference is IGeographicCoordinateSystem)
            {
                ISpatialReference pSpatialReference = GeometryHelper.GetSpatialByX(pArea.Centroid.X);
                IClone pClone = pPolygon as IClone;
                IGeometry pGeomClone = pClone.Clone() as IGeometry;
                pGeomClone.Project(pSpatialReference);
                pArea = pGeomClone as IArea;
                dblArea = pArea.Area;
            }

            //pRow["AREA"] = dblArea;

            ITopologicalOperator pTopo = pGeo as ITopologicalOperator;
            IGeometry pIntersectGeo = null;
            try
            {
                pIntersectGeo = pTopo.Intersect(pPolygon, esriGeometryDimension.esriGeometry2Dimension);
            }
            catch (Exception ex)
            {
                pIntersectGeo = null;
            }
            if (pIntersectGeo == null || pIntersectGeo.IsEmpty) return;
            pArea = pIntersectGeo as IArea;
            dblArea = Math.Abs(pArea.Area);
            pRow["INTERSECTAREA"] = dblArea;
            pRow["AREA"] = dblArea;

            pTable.Rows.Add(pRow);

        }

        /// <summary>
        /// 
        /// </summary>
        private void FillHashtable()
        {
            m_pCodeAndNameHash = new Hashtable();
            string aliasName = StatisticConfigHelper.StatisticConfig.植被绿化率统计.要素类名称;
            DataImportRule dataImportRuleCur = RuleConfig.DefaultImportRule;
            if (dataImportRuleCur == null) return;
            foreach (DlgTargetFeatureClass featureClass in dataImportRuleCur.dlgTargetFeatureClasses)
            {
                if (featureClass.FeatureClassName.Equals(aliasName, StringComparison.CurrentCultureIgnoreCase) ||
                    featureClass.FeatureClassName.ToLower().Contains(aliasName.ToLower()) ||
                    aliasName.ToLower().Contains(featureClass.FeatureClassName.ToLower()))
                {
                    m_pCodeAndNameHash = new Hashtable();
                    foreach (FeatureCode code in featureClass.featureCodes)
                    {
                        m_pCodeAndNameHash.Add(code.FCODE, code.FNAME);
                    }
                }
            }
        }

        private void FrmVegetable_Load(object sender, EventArgs e)
        {
            frmAddData = new OpenDataDialog();
            frmAddData.OnOkClick = new EventHandler(btnAddData_Click);
            frmAddData.MultiSelect = false;

            if (JHBHelper.ScaleValues != null)
            {
                foreach (int scale in JHBHelper.ScaleValues)
                {
                    this.cmbScale.Items.Add(scale.ToString());
                }
            }
            if (cmbScale.Items.Count > 0)
            {
                this.cmbScale.SelectedIndex = 0;
            }
        }
        /// <summary>
        /// 加载数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddData_Click(object sender, EventArgs e)
        {
            List<IDataset> pSelDatasets = frmAddData.GetSelectDatasets();
            if (pSelDatasets.Count > 0)
            {
                if (pSelDatasets[0].Type == esriDatasetType.esriDTFeatureClass)
                {
                    IFeatureClass pFeatCls = pSelDatasets[0] as IFeatureClass;
                    if (pFeatCls.ShapeType == esriGeometryType.esriGeometryPolygon && pFeatCls.FeatureType == esriFeatureType.esriFTSimple)
                    {
                        _AreaCreator.AddArea(pFeatCls);
                    }
                    else
                    {
                        MsgHelper.ShowInfomationMsgbox("您必须选择多边形要素类！");
                        return;
                    }
                }
                else
                {
                    MsgHelper.ShowInfomationMsgbox("您选择的不是矢量要素类，请重新选择！");
                    return;
                }
            }
            else
            {
                MsgHelper.ShowInfomationMsgbox("您没有选中的要素类，或选中要素类已破坏，请检查!");
            }
            frmAddData.Hide();
        }

        /// <summary>
        /// 绘制完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnDrawFinished(object sender, DrawArgs e)
        {
            if (sptbctlGeo.SelectedTab == sptbitmRegion)
                regionTree.SelectRegion(e.Geometry, e.Shift);
            else if (sptbctlGeo.SelectedTab == sptbitmSheet)
                _SheetCreator.SelectRegion(e.Geometry, e.Shift);

        }

        private void btnSelAllSheet_Click(object sender, EventArgs e)
        {
            foreach (GridRow r in spgrdSheet.PrimaryGrid.Rows)
            {
                if ((bool)r.Cells["colCheck"].Value == false)
                {
                    r.Cells["colCheck"].Value = true;
                    Mapsheet sheet = r.Tag as Mapsheet;
                    int idx = _SheetCreator.AllSheets.FindIndex(t => t.Code == sheet.Code);
                    if (idx > -1)
                    {
                        if (_SheetCreator.AllSheets[idx].Checked == false)
                            _SheetCreator.AllSheets[idx].Checked = true;
                    }
                }
            }
            _SheetCreator.ClearElement();
            _SheetCreator.DrawElements(_SheetCreator.CheckedSheets);
        }

        private void btnNoSelSheet_Click(object sender, EventArgs e)
        {
            foreach (GridRow r in spgrdSheet.PrimaryGrid.Rows)
            {
                if ((bool)r.Cells["colCheck"].Value == true)
                {
                    r.Cells["colCheck"].Value = false;
                    Mapsheet sheet = r.Tag as Mapsheet;
                    int idx = _SheetCreator.AllSheets.FindIndex(t => t.Code == sheet.Code);
                    if (idx > -1)
                    {
                        if (_SheetCreator.AllSheets[idx].Checked == true)
                            _SheetCreator.AllSheets[idx].Checked = false;
                    }
                }
            }
            _SheetCreator.ClearElement();
            _SheetCreator.DrawElements(_SheetCreator.CheckedSheets);
        }

        private void btnReverSelSheet_Click(object sender, EventArgs e)
        {
            foreach (GridRow r in spgrdSheet.PrimaryGrid.Rows)
            {
                if ((bool)r.Cells["colCheck"].Value == true)
                {
                    r.Cells["colCheck"].Value = false;
                    Mapsheet sheet = r.Tag as Mapsheet;
                    int idx = _SheetCreator.AllSheets.FindIndex(t => t.Code == sheet.Code);
                    if (idx > -1)
                    {
                        if (_SheetCreator.AllSheets[idx].Checked == true)
                            _SheetCreator.AllSheets[idx].Checked = false;
                    }
                }
                else if ((bool)r.Cells["colCheck"].Value == false)
                {
                    r.Cells["colCheck"].Value = true;
                    Mapsheet sheet = r.Tag as Mapsheet;
                    int idx = _SheetCreator.AllSheets.FindIndex(t => t.Code == sheet.Code);
                    if (idx > -1)
                    {
                        if (_SheetCreator.AllSheets[idx].Checked == false)
                            _SheetCreator.AllSheets[idx].Checked = true;
                    }
                }
            }
            _SheetCreator.ClearElement();
            _SheetCreator.DrawElements(_SheetCreator.CheckedSheets);
        }

        private void sptbctlGeo_SelectedTabChanged(object sender, SuperTabStripSelectedTabChangedEventArgs e)
        {
            cmbScale.Visible = this.sptbctlGeo.SelectedTab == sptbitmSheet;
            btnOpenFile.Visible = this.sptbctlGeo.SelectedTab == sptbitmArea;
            btnDrawExtent.Visible = this.sptbctlGeo.SelectedTab != sptbitmArea;
            IGraphicsContainer pGraphicsContainer = (IGraphicsContainer)(m_Application.Document as IMxDocument).ActiveView;
            pGraphicsContainer.DeleteAllElements();
            if (this.sptbctlGeo.SelectedTab == sptbitmSheet && _SheetCreator.CheckedSheets != null)
            {
                _SheetCreator.ClearElement();
                _SheetCreator.DrawElements(_SheetCreator.CheckedSheets);
            }
            if (this.sptbctlGeo.SelectedTab == sptbitmRegion && regionTree.DrawElements != null)
            {
                foreach (IElement ele in regionTree.DrawElements)
                {
                    ElementHelper.AddElement(ele, (m_Application.Document as IMxDocument).ActiveView.FocusMap);
                }
            }
            if (this.sptbctlGeo.SelectedTab == sptbitmArea && _AreaCreator.CheckedFeatures != null)
            {
                foreach (IElement ele in _AreaCreator.DrawElements)
                {
                    ElementHelper.AddElement(ele, (m_Application.Document as IMxDocument).ActiveView.FocusMap);
                }
            }
            (m_Application.Document as IMxDocument).ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics | esriViewDrawPhase.esriViewGeography, null, (m_Application.Document as IMxDocument).ActiveView.Extent);
        }

        private void cmbScale_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(cmbScale.Text)) return;
            if (_SheetCreator == null) return;
            _SheetCreator.ScaleValue = int.Parse(cmbScale.Text);
        }

        private void FrmVegetable_FormClosed(object sender, FormClosedEventArgs e)
        {
            (m_Application as IFramework).Tool = null;
            if (_SheetCreator != null) _SheetCreator.ClearElement();
            if (_ToolCreator != null) _ToolCreator.Clear();
            regionTree.ClearNodeCheck(regionTree.Nodes);
            regionTree.Clear();
        }

        private void btnSelAllArea_Click(object sender, EventArgs e)
        {
            _AreaCreator.Select(selType.All);
        }

        private void btnNoSelArea_Click(object sender, EventArgs e)
        {
            _AreaCreator.Select(selType.NONE);
        }

        private void btnReverSelArea_Click(object sender, EventArgs e)
        {
            _AreaCreator.Select(selType.REVERSE);
        }

        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            frmAddData.ShowDialog();
        }
    }
}
